package main

import (
	"fmt"
	"sync"
	"time"
)

func Worker(id int, jobs <-chan int, result chan<- int, wg *sync.WaitGroup) {
	for job := range jobs {
		fmt.Printf("worker %d starts to work on job %d\n", id, job)
		time.Sleep(time.Millisecond * 500)
		fmt.Printf("worker %d finished job %d\n", id, job)
		result <- job * 2
	}
	wg.Done()
}

func main() {
	const numJobs = 5
	jobs := make(chan int, numJobs)
	results := make(chan int, numJobs)

	wg := &sync.WaitGroup{}

	for i := 1; i <= 3; i++ {
		wg.Add(1)
		go Worker(i, jobs, results, wg)
	}

	for i := 1; i <= numJobs; i++ {
		jobs <- i
	}
	close(jobs)

	go func() {
		wg.Wait()
		close(results)
	}()

	for a := 1; a <= numJobs; a++ {
		<-results
	}

	// wg.Wait() // No need to wait here, the goroutine above handles closing results after workers are done
}
